import React, { useState, useEffect, ReactText, ChangeEvent } from 'react';
import { Tree, Input, Select } from 'antd';

const { Search } = Input;

interface MemberSelectPlusProps {
    value?: string[];
    placeholder?: string;
    childrenKey?: string;
    keyName?: string;
    data: any[];
    isOnlyLeaf: boolean;
    onChange?: (values: ReactText[]) => void;
}

interface TreeNode {}

const getParentKey = (key: any, tree: any): any => {
    let parentKey;
    for (let i = 0; i < tree.length; i++) {
        const node = tree[i];
        if (node.children) {
            if (node.children.some((item: any) => item.key === key)) {
                parentKey = node.key;
            } else if (getParentKey(key, node.children)) {
                parentKey = getParentKey(key, node.children);
            }
        }
    }
    return parentKey;
};

export default function MemberSelectPlus(props: MemberSelectPlusProps): JSX.Element {
    // const [selectedKeys, setSelectedKeys] = useState<string[]>([]);
    const [searchValue, setSearchValue] = useState('');
    const [expandedKeys, setExpandedKeys] = useState<ReactText[]>([]);
    const [checkedKeys, setCheckedKeys] = useState<ReactText[]>([]);
    const [autoExpandParent, setAutoExpandParent] = useState<boolean>(true);
    const [selectValue, setSelectValue] = useState<ReactText[]>([]);
    const [data, setData] = useState<Array<any>>([]);
    const [dataList, setDataList] = useState<Array<any>>([]);
    const [dataMap, setDataMap] = useState<Map<string, any>>(new Map());
    const [selectOption, setSelectOption] = useState<Array<{ label: string; value: string }>>([]);

    useEffect(() => {
        setData(props.data);
        const list: any[] = [];
        const generateList = (data: any) => {
            for (let i = 0; i < data.length; i++) {
                const node = data[i];
                const { key, title } = node;
                list.push({ key, title });
                if (node.children) {
                    generateList(node.children);
                }
            }
        };
        generateList(props.data);
        const key = props.keyName || 'key';
        const dataMap = list2Map(list, key);
        const option = list.map((item) => ({ label: item.title, value: item.key }));
        setSelectOption(option);
        setDataMap(dataMap);
        setDataList(list);
        setExpandedKeys(['1']);
        setAutoExpandParent(true);

        if (props.data && props.data.length) {
            setCheckedKeys(props.value || []);
            setSelectValue(props.value || []);
        }
    }, [props.data, props.keyName, props.value]);

    const tree2list = (treeData: any) => {
        const res = [];
        const queue = [];
        const childrenKey = props.childrenKey || 'children';
        queue.push(...treeData);
        while (queue.length) {
            const item: any = queue.shift();
            res.push(item);
            if (item[childrenKey] && Array.isArray(item[childrenKey]) && item[childrenKey].length) {
                queue.unshift(...item[childrenKey]);
            }
        }
        return res;
    };

    const list2Map = (nodeList: any[], key: string) => {
        const map = new Map();
        for (let i = 0; i < nodeList.length; i++) {
            const item = nodeList[i];
            map.set(item[key], item);
        }
        return map;
    };

    const pickLeaf = (nodeList: ReactText[]): ReactText[] => {
        const key = props.keyName || 'key';
        const childrenKey = props.childrenKey || 'children';
        const treeList = tree2list(data);
        const treeMap = list2Map(treeList, key);
        return nodeList.filter((item) => !(treeMap.get(item)[childrenKey] && treeMap.get(item)[childrenKey].length));
    };

    const onExpand = (expandedKeys: ReactText[]) => {
        setExpandedKeys(expandedKeys);
        setAutoExpandParent(false);
    };

    const onCheck = (checkedKeys: ReactText[] | { checked: ReactText[]; halfChecked: ReactText[] }) => {
        const res = props.isOnlyLeaf ? pickLeaf(checkedKeys as ReactText[]) : (checkedKeys as ReactText[]);
        console.log('onCheck', checkedKeys, res);
        setCheckedKeys(res);
        setSelectValue(res);
        props.onChange && props.onChange(res);
    };

    const onChange = (e: ChangeEvent<HTMLInputElement>) => {
        const { value } = e.target;
        const expandedKeys = dataList
            .map((item) => {
                if (item.title.indexOf(value) > -1) {
                    return getParentKey(item.key, data);
                }
                return null;
            })
            .filter((item, i, self) => item && self.indexOf(item) === i);
        setExpandedKeys(expandedKeys);
        setAutoExpandParent(true);
        setSearchValue(value);
    };

    const handleChangeSelect = (values: string[]): void => {
        console.log(values);
        setSelectValue(values);
        setCheckedKeys(values);
        props.onChange && props.onChange(values);
    };

    return (
        <div className="d-f">
            <div className="flex1 s0 d-f fd-c mr8">
                <Search placeholder={props.placeholder || ''} onChange={onChange} />
                <Tree
                    className="bg-w bor-b bor-l bor-r b-side-s p8 h100"
                    onExpand={onExpand}
                    expandedKeys={expandedKeys}
                    autoExpandParent={autoExpandParent}
                    treeData={data}
                    checkable
                    onCheck={onCheck}
                    checkedKeys={checkedKeys}
                />
            </div>
            <div className="flex1 s0 bg-w bor b-side-s">
                {/* <div className="bor-b b-side-s p8">
                    <div className="fs16">新选择成员：</div>
                    <Select
                        mode="multiple"
                        open={false}
                        bordered={false}
                        value={selectValue}
                        style={{ width: '100%' }}
                        options={[]}
                        onChange={handleChangeSelect}
                    />
                </div> */}
                <div>
                    <div className=" bor-b b-side-s plr8 ptb4">已添加成员({checkedKeys.length})</div>
                    <Select
                        mode="multiple"
                        open={false}
                        bordered={false}
                        value={selectValue as []}
                        style={{ width: '100%' }}
                        options={selectOption}
                        onChange={handleChangeSelect}
                    />
                </div>
            </div>
        </div>
    );
}
